﻿using System;
using System.Collections;
using System.IO;
using Unity.VisualScripting;
using UnityEditor;
using UnityEngine;
using UnityEngine.Networking;

namespace ns
{
    public enum ConfigType
    {
        txt,
        json,
        xml,
        csv
    }
    public class ConfigurationReader 
    {
        /// <summary>
        /// 简单模式，没找到文件，程序就阻塞
        /// 不可以向下检索
        /// 有匹配失败的自动匹配
        /// </summary>
        /// <param name="filename"></param>
        /// <param name="isAutoMatch">是否启用找寻失败后的自动匹配</param> 
        /// <param name="index">匹配过程的下一次索引</param> 
        /// <returns></returns>
        public static string GetConfigFile(string filename, float timeout = 0.1f, bool isAutoMatch = true, int index = 0)
        {
            #region
            if (filename.Split('.').Length == 1) filename += '.' + Enum.GetNames(typeof(ConfigType))[index++];
            string url = Path.Combine(Application.streamingAssetsPath, filename);
            #endregion
            UnityWebRequest www = UnityWebRequest.Get(url);
            DateTime time = DateTime.Now;
            TimeSpan MatchInterval = TimeSpan.FromSeconds(timeout); // 创建一个表示超时秒数的TimeSpan对象
            www.SendWebRequest();   //发送请求，这一步真的很重要
            //还没有成功时，一直循环
            while (www.result != UnityWebRequest.Result.Success) 
            {
                Debug.Log("正在堵塞，全力获取配置文件：" + filename);
                if (isAutoMatch)
                {
                    //超时后自动匹配
                    if (DateTime.Now >=time + MatchInterval)
                    {
                        string[] oldTemp = filename.Split('.');
                        filename = oldTemp[0];
                        if (oldTemp[1] == Enum.GetNames(typeof(ConfigType))[index])
                        {
                            index++;
                        }
                        string end = '.' + Enum.GetNames(typeof(ConfigType))[index++];
                        filename += end;
                        if (index > Enum.GetNames(typeof(ConfigType)).Length-1) return null;
                        return GetConfigFile(filename, timeout, isAutoMatch, index);
                    }
                }
                else
                {
                    if (DateTime.Now >= time + MatchInterval) return null;
                }
            }
            return www.downloadHandler.text;
        }
        /// <summary>
        /// 可以向下层次检索
        /// 因为协程检索会有微小的滞后性，所以这个方法不适合在Start等即刻需要数据的地方中使用。
        /// </summary>
        /// <param name="filename"></param>
        /// <param name="onComplete"></param>
        /// <returns></returns>
        public static IEnumerator GetConfigFile(string filename, Action<string> onComplete)
        {
            Debug.Log("正在协程，尝试获取配置文件：" + filename);
            string url = Path.Combine(Application.streamingAssetsPath, filename);
            UnityWebRequest www = UnityWebRequest.Get(url);          
            yield return www.SendWebRequest();
            if (www.result == UnityWebRequest.Result.Success)
            {
                onComplete?.Invoke(www.downloadHandler.text);
                yield break;
            }
            else
            {
                bool isfound = false;
                onComplete += (result) => { isfound = true; };
                yield return GameController.Instance.StartCoroutine
                    (IterationDictionary(Application.streamingAssetsPath, filename, www, onComplete));
                if (!isfound) Debug.LogError("没找到文件：" + filename + "，请检查文件后缀是否正确");
            }
        }
        private static IEnumerator IterationDictionary(string parentDir, string filename, UnityWebRequest www, Action<string> onComplete)
        {
            if (Directory.Exists(parentDir))
            {
                string[] childDirs = Directory.GetDirectories(parentDir);
                //先找父文件夹的所有子文件夹的所有文件
                foreach (string childDir in childDirs)
                {
                    string fileUrl = childDir + "/" + filename;
                    www = UnityWebRequest.Get(fileUrl);
                    yield return www.SendWebRequest();   //发送请求，这一步真的很重要
                    if (www.result == UnityWebRequest.Result.Success)
                    {
                        onComplete?.Invoke(www.downloadHandler.text);
                        yield break;
                    }
                }
                //再把父文件夹的所有子文件夹当成父文件夹重复（此时父文件夹的同级文件在上次完成查找）
                foreach (string childDir in childDirs)
                {
                    bool isfound = false;
                    onComplete += (result) => { isfound = true; };               
                    yield return GameController.Instance.StartCoroutine(IterationDictionary(childDir, filename, www, onComplete));
                    if (isfound)
                    {
                        onComplete?.Invoke(www.downloadHandler.text);
                        yield break;                 
                    }
                }
            }
            yield break;
        }

        public static void Reader(string fileContent,Action<string> handler)
        {
            using (StringReader reader = new StringReader(fileContent))
            {
                string line;
                while ((line = reader.ReadLine()) != null)
                {
                    handler(line);
                }
            }
        }
    }
}